package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.commons.exception.ServiceException;
import cn.tedu.csmall.commons.web.ServiceCode;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.CategoryAttributeTemplateMapper;
import cn.tedu.csmall.product.mapper.CategoryMapper;
import cn.tedu.csmall.product.mapper.SPUMapper;
import cn.tedu.csmall.product.pojo.entity.BrandCategory;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.entity.CategoryAttributeTemplate;
import cn.tedu.csmall.product.pojo.entity.SPU;
import cn.tedu.csmall.product.pojo.param.CategoryInsertParam;
import cn.tedu.csmall.product.pojo.param.CategoryUpdateInfoParam;
import cn.tedu.csmall.product.pojo.vo.CategoryListVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.pojo.vo.CategoryTreeVO;
import cn.tedu.csmall.product.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    CategoryMapper mapper;
    @Autowired
    BrandCategoryMapper brandCategoryMapper;
    @Autowired
    SPUMapper spuMapper;
    @Autowired
    CategoryAttributeTemplateMapper categoryAttributeTemplateMapper;
    @Override
    public void insert(CategoryInsertParam categoryInsertParam) {
        log.debug("开始处理【添加类别】的业务，参数：{}",categoryInsertParam);
        QueryWrapper<Category> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("name",categoryInsertParam.getName());
        int countByName = mapper.selectCount(queryWrapper);
        log.debug("根据类别名称统计匹配的类别数量，结果：{}", countByName);
        if(mapper.selectCount(queryWrapper)>0){
            String message="添加类别失败，类别名称已被占用!";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_CONFLICT);
        }

        Long parentId=categoryInsertParam.getParentId();
        Integer depth=1;
        CategoryStandardVO parentCategory=null;
        if(parentId!=0){
             parentCategory= mapper.getStandardById(parentId);
            if(parentCategory==null){
                String message = "添加类别失败，父级类别不存在！";
                log.warn(message);
                throw new ServiceException(message,ServiceCode.ERR_NOT_FOUND);
            }else {
                depth=parentCategory.getDepth()+1;
            }
        }



        Category category=new Category();
        BeanUtils.copyProperties(categoryInsertParam,category);
        category.setDepth(depth);
        category.setIsParent(0);
        category.setGmtCreate(LocalDateTime.now());
        category.setGmtModified(LocalDateTime.now());
        log.debug("准备将新的类别数据写入到数据库，数据：{}", category);
        int row = mapper.insert(category);
        if(row !=1){
            String message="添加类别失败，服务器忙，请稍后再试!";
            log.warn(message);
            throw new ServiceException(message, ServiceCode.ERR_INSERT);
        }

        if(parentId !=0 && parentCategory.getIsParent()==0){
            Category update=new Category();
            update.setId(parentId);
            update.setIsParent(1);
            int rows = mapper.updateById(update);
            if(rows!=1){
                String message="添加类别失败，服务器忙，请稍后再试!";
                log.warn(message);
                throw new ServiceException(message, ServiceCode.ERR_INSERT);
            }
        }

        log.debug("将新的类别数据写入到数据库，完成！");
    }

    @Override
    public void deleteById(Long categoryId) {
        log.debug("开始处理【删除分类】的业务，参数：{}", categoryId);
        // 检查分类是否存在，如果不存在，则抛出异常
        QueryWrapper<Category> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("id", categoryId);
        int countById = mapper.selectCount(queryWrapper1);
        log.debug("根据分类ID统计匹配的分类数量，结果：{}", countById);
        if (countById == 0) {
            String message = "删除分类失败，分类数据不存在！";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_NOT_FOUND);
        }
        //检查是否有品牌关联此分类
        QueryWrapper<BrandCategory> queryWrapper2=new QueryWrapper<>();
        queryWrapper2.eq("category_id",categoryId);
        int countByCategoryId2 = brandCategoryMapper.selectCount(queryWrapper2);
        log.debug("根据分类ID统计匹配的分类数量，结果：{}", countByCategoryId2);
        if(countByCategoryId2>0){
            String message="删除分类失败，仍有品牌关联此分类!";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_CONFLICT);
        }

        //检查是否有SPU关联此分类
        QueryWrapper<SPU> queryWrapper3=new QueryWrapper<>();
        queryWrapper3.eq("category_id",categoryId);
        int countByCategoryId3 = spuMapper.selectCount(queryWrapper3);
        log.debug("根据分类ID统计匹配的分类数量，结果：{}", countByCategoryId3);
        if(countByCategoryId3>0){
            String message="删除分类失败，仍有spu关联此分类!";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_CONFLICT);
        }
        //检查是否有属性模版关联此类别
        QueryWrapper<CategoryAttributeTemplate> queryWrapper4=new QueryWrapper<>();
        queryWrapper4.eq("category_id",categoryId);
        int countByCategoryId4 = categoryAttributeTemplateMapper.selectCount(queryWrapper4);
        log.debug("根据分类ID统计匹配的分类数量，结果：{}", countByCategoryId4);
        if(countByCategoryId4>0){
            String message="删除分类失败，仍有属性模版关联此分类!";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_CONFLICT);
        }

        Integer isParent = mapper.getStandardById(categoryId).getIsParent();
        if(isParent==1){
            String message = "删除类别失败，该类别仍包含子级类别！";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_CONFLICT);
        }

        Long parentId = mapper.getStandardById(categoryId).getParentId();
        int row = mapper.deleteById(categoryId);
        if(row !=1){
            String message="删除类别失败，服务器忙，请稍后再试!";
            log.warn(message);
            throw new ServiceException( message,ServiceCode.ERR_DELETE);
        }


        QueryWrapper<Category> queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.eq("parent_id", parentId);
        int count = mapper.selectCount(queryWrapper5);
        log.debug("根据分类ID统计匹配的分类子集数量，结果：{}", count);
        if (count == 0) {
            Category update=new Category();
            update.setId(parentId);
            update.setIsParent(0);
            int i = mapper.updateById(update);
            if(i !=1){
                String message="修改类别失败，服务器忙，请稍后再试!";
                log.warn(message);
                throw new ServiceException( message,ServiceCode.ERR_UPDATE);
            }
        }
    }

    @Override
    public void update(CategoryUpdateInfoParam updateInfoParam) {
        Category category=new Category();
        BeanUtils.copyProperties(updateInfoParam,category);
        mapper.updateById(category);
    }

    @Override
    public void setEnable(Long id) {
        set(id,1);
    }

    @Override
    public void setDisable(Long id) {
        set(id,0);
    }

    @Override
    public List<CategoryTreeVO> listTree() {
        List<CategoryTreeVO> categoryTree=new ArrayList<>();

        List<CategoryListVO> categoryList = mapper.list();
        Map<Long,CategoryListVO> allCategoryMap= transformListToMap(categoryList);
        for (Long key: allCategoryMap.keySet()) {
            CategoryListVO mapItem =allCategoryMap.get(key);
            if (mapItem.getParentId() == 0){
                CategoryTreeVO categoryTreeVO=convertListItemToTreeItem(mapItem);
                categoryTree.add(categoryTreeVO);

                fillChildren(mapItem,categoryTreeVO,allCategoryMap);
            }
        }
        return categoryTree;
    }

    private Map<Long, CategoryListVO> transformListToMap(List<CategoryListVO> categoryList) {
        Map<Long, CategoryListVO> categoryMap = new LinkedHashMap<>();
        for (CategoryListVO categoryListItemVO : categoryList) {
            if (categoryListItemVO.getEnable() == 0) {
                continue;
            }
            categoryMap.put(categoryListItemVO.getId(), categoryListItemVO);
        }
        return categoryMap;
    }

    private void fillChildren(CategoryListVO listItem, CategoryTreeVO currentTreeItem, Map<Long, CategoryListVO> allCategoryMap) {
        if (listItem.getIsParent() == 1) {
            currentTreeItem.setChildren(new ArrayList<>());
            Set<Long> keySet = allCategoryMap.keySet();
            for (Long key : keySet) {
                CategoryListVO mapItem = allCategoryMap.get(key);
                if (mapItem.getParentId() == listItem.getId()) {
                    CategoryTreeVO categoryTreeSubItemVO = convertListItemToTreeItem(mapItem);
                    currentTreeItem.getChildren().add(categoryTreeSubItemVO);
                    if (mapItem.getIsParent() == 1) {
                        fillChildren(mapItem, categoryTreeSubItemVO, allCategoryMap);
                    }
                }
            }
        }
    }

    private CategoryTreeVO convertListItemToTreeItem(CategoryListVO listItem) {
        return new CategoryTreeVO()
                .setValue(listItem.getId())
                .setLabel(listItem.getName());
    }


    @Override
    public CategoryStandardVO getStandardById(Long id) {
        CategoryStandardVO categoryStandard = mapper.getStandardById(id);
        return categoryStandard;
    }

    private void set(Long id,Integer enable){
        Category category=new Category();
        category.setId(id);
        category.setEnable(enable);
        int row = mapper.updateById(category);
        if(row!=1){
            String message=enableContent[enable]+"失败";
            log.warn(message);
            throw new ServiceException(message,ServiceCode.ERR_UPDATE);
        }
    }

    @Override
    public List<CategoryListVO> listByParentId(Long parentId) {
        List<CategoryListVO> list = mapper.listByParentId(parentId);
        return list;
    }
}
